package com.googlecode.olabs.common.client.contact.field;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import com.googlecode.olabs.common.client.contact.ContactException;

public abstract class AbstractField implements Field {

	private Set<String> m_subTypes;
	private List<String> m_value = new ArrayList<String>(3);

	protected AbstractField() {
		m_subTypes = new HashSet<String>();
	}

	public final boolean addSubType(String subType) {
		return m_subTypes.add(subType);
	}

	public final boolean removeSubType(String subType) {
		return m_subTypes.remove(subType);
	}

	public final Set<String> getSubTypes() {
		return new HashSet<String>(m_subTypes);
	}

	public final void clearSubTypes() {
		m_subTypes.clear();
	}

	public List<String> getValue() {
		return m_value;
	}

	public void setValue(List<String> value) throws ContactException {
		m_value = value;
	}

	public Object clone() {
		AbstractField clone = getInstanceForClone();
		clone.m_subTypes = getSubTypes();
		return clone;
	}

	protected abstract AbstractField getInstanceForClone();

	public boolean equals(Object obj) {
		if (obj instanceof Field) {
			Field other = (Field) obj;
			if (!getType().equals(other.getType())) {
				return false;
			}
			if (!getValue().equals(other.getValue())) {
				return false;
			}
			return getSubTypes().equals(other.getSubTypes());
		}
		return false;
	}

	public int hashCode() {
		StringBuffer buffer = new StringBuffer(getType());
		for (String subType : getSubTypes()) {
			buffer.append(subType);
		}
		buffer.append(getValue());
		return buffer.toString().hashCode();
	}
}
